﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Wilke.Interactive.Drone.PlayGround
{
    /// <summary>
    /// Interaction logic for JoystickBase.xaml
    /// </summary>
    public partial class JoystickBase : UserControl
    {
        public event EventHandler<DroneCoordinatesChangedEventArgs> DroneCoordinatesChanged;

        public JoystickBase()
        {
            InitializeComponent();
        }

        public Single DroneHeight
        {
            set
            {
                Matrix matrix;
                MatrixTransform joystickBoxTransform = JoystickBox.RenderTransform as MatrixTransform;

                if (joystickBoxTransform != null)
                {
                    Single height = value;
                    if (Math.Abs(height) > 1)
                    {
                        height = 1 * Math.Sign(height);
                    }
                    matrix = joystickBoxTransform.Matrix;
                    matrix.OffsetY = (JoystickBox.ActualHeight - grid.ActualWidth)/ 2 * height;
                    joystickBoxTransform.Matrix = matrix;

                    JoystickThumb.ShowOuterGlow();
                }
            }
        }

        public Single Yaw
        {
            set
            {
                Matrix matrix;
                MatrixTransform joystickBoxTransform = JoystickBox.RenderTransform as MatrixTransform;

                if (joystickBoxTransform != null)
                {
                    Single yaw = value;
                    if (Math.Abs(yaw) > 1)
                    {
                        value = 1 * Math.Sign(yaw);
                    }
                    matrix = joystickBoxTransform.Matrix;
                    matrix.OffsetX = grid.ActualWidth / 2 * yaw;
                    joystickBoxTransform.Matrix = matrix;

                    JoystickThumb.ShowOuterGlow();
                }
            }
        }

        private void userControl_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            Matrix matrix;
            MatrixTransform transform = JoystickBox.RenderTransform as MatrixTransform;

            double positionX = e.ManipulationOrigin.X + e.DeltaManipulation.Translation.X;
            double positionY = e.ManipulationOrigin.Y + e.DeltaManipulation.Translation.Y;

            if (positionX < (JoystickBox.Margin.Left - JoystickBox.ActualWidth / 2) || positionX > this.ActualWidth - JoystickBox.Margin.Right + JoystickBox.ActualWidth / 2)
            {
                e.Handled = true;
                return; 
            }

            if (positionY < (JoystickBox.Margin.Top- JoystickBox.ActualHeight / 2) || positionY > this.ActualHeight - JoystickBox.Margin.Bottom + JoystickBox.ActualHeight / 2)
            {
                e.Handled = true;
                return;
            }

            if (transform != null)
            {
                matrix = transform.Matrix;
                
                matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);

                transform.Matrix = matrix;

                UpdateValues(matrix);
            }

            e.Handled = true;
        }

        private void userControl_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
        {
            e.ManipulationContainer = this;
            e.Handled = true;
        }

        private void CenterThumb()
        {
            Matrix matrix = ((MatrixTransform)JoystickBox.RenderTransform).Matrix;
            matrix.OffsetX = 0;
            matrix.OffsetY = 0;
            JoystickBox.RenderTransform = new MatrixTransform(matrix);
            UpdateValues(matrix);
        }

        private void userControl_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            CenterThumb();
        }

        private void UpdateValues(Matrix matrix)
        {
            Single yaw = (float)(matrix.OffsetX / JoystickBox.ActualWidth * 2);
            Single height = (float)(matrix.OffsetY / JoystickBox.ActualHeight * 2);

            if (DroneCoordinatesChanged != null)
            {
                DroneCoordinatesChanged(this, new DroneCoordinatesChangedEventArgs(0, 0, yaw, -height));
            }
        }
    }
}
